﻿using System.Collections;
using UnityEngine;
using System;
using System.Threading;
using System.Linq;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.IO;
using System.Text;
using IMIForUnity;


namespace IMIForUnity
{

	public partial class BodyMeaMgrImp
	{

		//For Waist;
		//public KDXIMILineAnalysis mWaistLineAnalysis;
//		public ClusterSmoothTool waistSmthWideness;
//		//public ClusterSmoothTool waistSmthThickness;
//		public FloatSmoothTool waistSmthThickness;

		public ArrayList waistSmthWidthArr=new ArrayList();
		public ArrayList waistSmthThickArr=new ArrayList();



		float waistThicknessRatio = 0.94f;
		float waistWidenessRatio = 0.94f;
		float waistRatio = 0.98f;  //the value detected by knt is a bit too large. 

		public float waistWideness = 0;  //We set the distance between shoulders *chestWidShoulderWidthRatio as the wideness of chest.
		public float waistThickness = 0f;

		float waistWidShoulderWidthRatio = 1f;



		//because the depth valuse in side posture is on the surface.
		                         //Which seems a bit too close to the device as the depth of waist. So we 
		                          // add a adjust value,  adjustDeepingLengthForSideWaist, now the value is 80mm.


		public void ProcessWaistFront (int userID, bool isDrawOnDepthMap)
		{
			GetPlayerJointPixPos (userID, ref hipsPixPosX, ref hipsPixPosY, ref hipsPixPosZ, 
			                     ImiSkeleton.Index.HIP_CENTER, isDrawOnDepthMap);
			int w = DEPTHWIDTH;
			int h = DEPTHHEIGHT;
			
			//int waistDepth=(ushort)depthPlayerDataOriginal[hipsPixPosY*w+ hipsPixPosX]>>3;
			GetWaistFrontWidth (depthPlayerDataOriginal, hipsPixPosX, hipsPixPosY, boundThreshval, true);
		}

		public float tmpWid;

		//For Front
		//In IMI for now we just use hisps pixpos as the waist pixpos. because it seems the hips pos of IMI is a bit higher than usually
		void GetWaistFrontWidth (ushort[] _depthPlayerDataOriginal, int waistPixPosX, int waistPixPosY, 
		                         ushort boundThreshval, bool isDrawOrNot)
		{
			int dw = DEPTHWIDTH;
			int dh = DEPTHHEIGHT;


			if(IMIBodyMeaTool.DoesPixBelongToPlayers(dw,dh,waistPixPosX,waistPixPosY, _depthPlayerDataOriginal))
			{
				Vector2 MinWaistPixPos = IMIBodyMeaTool.GetContourMinEnd (dw, dh, waistPixPosX, waistPixPosY, _depthPlayerDataOriginal, boundThreshval);
				Vector2 MaxWaistPixPos = IMIBodyMeaTool.GetContourMaxEnd (dw, dh, waistPixPosX, waistPixPosY, _depthPlayerDataOriginal, boundThreshval);
								
				//		Vector2 resultWaistEnds = mWaistLineAnalysis.GetAdjustetdWaistEnds( _depthPlayerDataOriginal,
				//		                                                                    (int)MinWaistPixPos.x,
				//		                                                                    (int)MaxWaistPixPos.x,
				//		                                                                    (int)MinWaistPixPos.y);
								
				Vector2 resultWaistEndMin = Vector2.zero;  //this is the pix pos of 2 ends of waist
				Vector2 resultWaistEndMax = Vector2.zero;  //this is the pix pos of 2 ends of waist
				
				IMIBodyMeaTool.GetFinalFrontEnds(dw,dh,_depthPlayerDataOriginal, new Vector2(waistPixPosX,waistPixPosY), 
				                                 MinWaistPixPos,MaxWaistPixPos,ref resultWaistEndMin,ref resultWaistEndMax,3.6f,9f);
				
				
				
				if (isDrawOrNot) {
					DrawHorilineOnUserDepthColor (allUsersDepthData, dw, dh, (int)MinWaistPixPos.x, (int)MaxWaistPixPos.x, (int)MaxWaistPixPos.y, 255, 255, 0, 255);
					DrawHorilineOnUserDepthColor (allUsersDepthData, dw, dh, (int)resultWaistEndMin.x, (int)resultWaistEndMax.x, (int)resultWaistEndMax.y, 255, 0, 0, 255);
				}
				
//				int WaistDepthMinEnd = ((_depthPlayerDataOriginal [((int)(resultWaistEndMin.y)) * dw + ((int)(resultWaistEndMin.x))]) >> 3);
//				int WaistDepthMaxEnd = ((_depthPlayerDataOriginal [((int)(resultWaistEndMax.y)) * dw + ((int)(resultWaistEndMax.x))]) >> 3);
//				int waistDepth = (WaistDepthMinEnd + WaistDepthMaxEnd) / 2;

				int waistDepth=(_depthPlayerDataOriginal [((int)(waistPixPosY)) * dw + waistPixPosX]>>3);  //in mm

				tmpWid = GetThicknessBy2PixPoses (resultWaistEndMin, resultWaistEndMax, waistDepth);
//				if(tmpWid<0.2f)
//				{
////					Debug.LogWarning("Small waist Waist Pix Pos X: "+ waistPixPosX+ "Min X : "+ resultWaistEndMin.x.ToString()
////					                 +"Max X:"+resultWaistEndMax.x.ToString()+"result waist width strange "+ tmpWid.ToString());
//
//					Debug.LogWarning("Small waist Waist Pix Pos Y: "+ waistPixPosY+ "Min Y : "+ resultWaistEndMin.y.ToString()
//					                 +"Max Y:"+resultWaistEndMax.y.ToString()+"Depth "+waistDepth.ToString());//+"  "+WaistDepthMaxEnd.ToString()+"  "+WaistDepthMinEnd.ToString());
//				}
//				else
//				{
////					Debug.LogWarning("Normal waist Waist Pix Pos X: "+ waistPixPosX+ "Min X : "+ resultWaistEndMin.x.ToString()
////					                 +"Max X:"+resultWaistEndMax.x.ToString()+"result waist width normal "+ tmpWid.ToString());
//
//					Debug.LogWarning("Normal waist Waist Pix Pos Y: "+ waistPixPosY+ "Min Y : "+ resultWaistEndMin.y.ToString()
//					                 +"Max Y:"+resultWaistEndMax.y.ToString()+"Normal Depth "+waistDepth.ToString());//+"  "+WaistDepthMaxEnd.ToString()+"  "+WaistDepthMinEnd.ToString());
//
//					
//				}


				if ((tmpWid > 0.18f)&&(waistDepth>1400)) {
					waistSmthWidthArr.Add(tmpWid);
//					waistSmthWideness.InsertValue (tmpWid);
//					waistWideness = waistSmthWideness.GetFilteredValue () * waistWidenessRatio;	
				}	
			}
		}



		public void ProcessWaistSide(int userID, bool isDrawOnDepthMap)
		{
			//method before 1121
//			int w = DEPTHWIDTH;
//			int h = DEPTHHEIGHT;
//			GetPlayerJointPixPos (userID, ref hipsPixPosX, ref hipsPixPosY, ref hipsPixPosZ, 
//			                     ImiSkeleton.Index.HIP_CENTER, isDrawOnDepthMap);
//
//
//
//
//			if((hipsPixPosX>0)&&(hipsPixPosX<w)&&
//			   (hipsPixPosY>0)&&(hipsPixPosY<h))
//			{
//			//we add a adjusting deeping value on the waist surface depth.
//				int tempPlayerIndex = depthPlayerDataOriginal  [hipsPixPosY *w +hipsPixPosX] & 7;
//				
//				
//				//Only when the key pix pos symplify an player pixel.
//				if(tempPlayerIndex>0)
//				{
//					int WaistSideDepth=((depthPlayerDataOriginal [hipsPixPosY *w +hipsPixPosX]) >> 3)+adjustDeepingLengthForSideWaist;
//
//					float waistWidthRecordSide= GetThicknessFromOnePixPos(depthPlayerDataOriginal, 
//					                  w, 
//					                  h, 
//					                  hipsPixPosX,
//					                  hipsPixPosY,
//					                  boundThreshval,			               
//					                  WaistSideDepth, 
//					                  isDrawOnDepthMap);
//
//					waistSmthThickArr.Add(waistWidthRecordSide);
////					waistSmthThickness.InsertValue (waistWidthRecordSide);
////					waistThickness = waistSmthThickness.GetFilteredValue () * waistThicknessRatio;
//
//				}
//			}




			//method after 11 21

			int dw = DEPTHWIDTH;
			int dh = DEPTHHEIGHT;
			
			
			int hipsMidPixPosX=0;
			int hipsMidPixPosY=0;
			int hipsMidPixPosZ=0;
			
			GetPlayerJointPixPos (userID, ref hipsMidPixPosX, ref hipsMidPixPosY, ref hipsMidPixPosZ, 
			                     ImiSkeleton.Index.HIP_CENTER,false);
			
			int hipleftX=0;
			int hipleftY=0;
			int hipleftZ=0;
			
			GetPlayerJointPixPos (userID, ref hipleftX, ref hipleftY, ref hipleftZ, 
			                     ImiSkeleton.Index.HIP_LEFT,false);
			
			
			//To measure the hips thickness.
			int hipssideupx=RangeValue(hipsMidPixPosX, 0 ,dw);;
			//int hipssideupy=RangeValue((hipsMidPixPosY+(hipsMidPixPosY-hipleftY)*2),0 ,dh); 
			int hipssideupy=RangeValue((hipsMidPixPosY+((hipsMidPixPosY-hipleftY)/2)),0 ,dh); 


			int hipssidedownx=RangeValue(hipsMidPixPosX, 0 ,dw);
			int hipssidedowny=RangeValue(hipsMidPixPosY-(hipsMidPixPosY-hipleftY)/2, 0 ,dh);
			
			if(hipssideupy==hipssidedowny)
			{
				hipssideupy=hipssidedowny+1;
			}
						
			Vector2 HipsUpPixPos = new Vector2(hipssideupx,hipssideupy );
			Vector2 HipsDownPixPos = new Vector2(hipssidedownx,hipssidedowny );
						
			//we add a adjusting deeping value on the waist surface depth.
			
			//method 1 get the thicknest part of the hips side	by using 2 pixposes
			int tempPlayerIndex0 = depthPlayerDataOriginal  [hipssidedowny *dw +hipssidedownx] & 7;
			int tempPlayerIndex1 = depthPlayerDataOriginal  [hipssideupy *dw +hipssideupx] & 7;
			
			
			//Only when the key pix pos symplify an player pixel.
			if((tempPlayerIndex0>0)&&(tempPlayerIndex1>0)&&(tempPlayerIndex0== tempPlayerIndex1 ))
			{
				
				float WaistSideTmp=GetThicknessFromPixPosesArr(dw,dh,depthPlayerDataOriginal,
				                                             boundThreshval,HipsUpPixPos,HipsDownPixPos,adjustDeepingLengthForSideWaist, isDrawOnDepthMap);	
				
				
				//Debug.Log("+++++++++++++++++++++++++++hips side tmep: "+hipsSideTmp.ToString());
				//					hipsSmthThickness.InsertValue (hipsSideTmp);
				//					hipsThickness=hipsSmthThickness.GetFilteredValue();
				
				waistSmthThickArr.Add(WaistSideTmp);
			}



		}



		public float  GetWaistGirth( )
		{
			return IMIBodyMeaTool.CalculateWaistGirth(waistWideness, waistThickness,waistRatio);
			
		}





	}
}
